$OpenBSD: patch-libapp_dbg_cpp,v 1.1 2015/07/01 11:33:50 bluhm Exp $
--- libapp/dbg.cpp.orig	Fri Feb  9 07:06:37 2001
+++ libapp/dbg.cpp	Thu Jan  8 21:02:01 2015
@@ -20,321 +20,14 @@ void dbgout( const char* fmt, ... )
     char str[4096];
     va_list v;
     va_start( v, fmt );
-    vsprintf( str, fmt, v );
-    strcat( str, "\n" );
+    vsnprintf( str, sizeof(str), fmt, v );
+    va_end(v);
 #ifdef _UNIX
-    fputs( str, stderr );
+    fprintf( stderr, "%s\n", str );
 #endif
 #ifdef _WIN32
     ::OutputDebugString( str );
 #endif
-}
-
-/*
- * Heap management using operator new/delete.  These routines use unbalanced
- * binary trees to keep track of allocations in an attempt to make them fast
- * yet simple.
- *
- * The trees for scalar and vector allocations are completely separate so
- * that trying to deallocate memory with the wrong version of operator
- * delete will always fail.
- *
- * Global operator new is redefined to pass the file and line where the
- * allocation occurred to facilitate memory leak debugging.  Unfortunately,
- * it doesn't seem to be possible to redefine operator delete.
- *
- * Each block of memory consists of an alloc_node header, the requested
- * memory block, and two-byte guards before and after the requested memory
- * block.  The requested memory block is filled with a semi-random byte
- * value to ensure that the caller does not rely on any particular initial
- * bit pattern (eg. a block of zeros or NULLs).  It is refilled with a
- * (possibly different) byte value after deallocation to ensure that the
- * caller doesn't attempt to use the freed memory.
- *
- * NOTES:
- * It is perfectly valid to allocate a block of length zero.  The returned
- * block should have a length of 1.  This simplifies algorithms, especially
- * those that do vector allocation based on an unsigned input parameter.  It
- * is also valid to delete a NULL block.  This simplifies object destruction
- * by alleviating the need for if() guards.  These rules have been around
- * since C++ was born but most people don't seem to know or care.
- */
-
-struct alloc_node
-{
-    alloc_node* lptr;
-    alloc_node* rptr;
-    size_t      len;
-    CPCHAR      file;
-    UINT        line;
-};
-
-static alloc_node* g_heap = NULL;
-static alloc_node* g_vector_heap = NULL;
-
-// Our magic guard bytes
-static BYTE g_guard[] =
-{
-    0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
-    0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF
-};
-
-void* operator new( size_t n, CPCHAR file, UINT line )
-{
-    BYTE* pmem = NULL;
-    if( !n ) n = 1;
-    alloc_node* pnode = (alloc_node*)malloc( n + 2*sizeof(g_guard) + sizeof(alloc_node) );
-    if( pnode )
-    {
-        pmem = (BYTE*)pnode + sizeof(alloc_node) + sizeof(g_guard);
-        memcpy( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) );
-        memset( pmem, time(NULL), n );
-        memcpy( pmem + n, g_guard, sizeof(g_guard) );
-
-        pnode->lptr = pnode->rptr = NULL;
-        pnode->len = n;
-        pnode->file = file;
-        pnode->line = line;
-        alloc_node** ppuplink = &g_heap;
-        alloc_node* pcur = g_heap;
-        while( pcur )
-        {
-            if( pnode == pcur )
-            {
-                dbgout( "*** FATAL: duplicate memory allocated ***" );
-                assert( false );
-                exit( -1 );
-            }
-            if( pnode < pcur )
-            {
-                ppuplink = &pcur->lptr;
-                pcur = pcur->lptr;
-            }
-            else
-            {
-                ppuplink = &pcur->rptr;
-                pcur = pcur->rptr;
-            }
-        }
-        *ppuplink = pnode;
-    }
-
-    return pmem;
-}
-
-void* operator new[]( size_t n, CPCHAR file, UINT line )
-{
-    BYTE* pmem = NULL;
-    if( !n ) n = 1;
-    alloc_node* pnode = (alloc_node*)malloc( n + 2*sizeof(g_guard) + sizeof(alloc_node) );
-    if( pnode )
-    {
-        pmem = (BYTE*)pnode + sizeof(alloc_node) + sizeof(g_guard);
-        memcpy( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) );
-        memset( pmem, time(NULL), n );
-        memcpy( pmem + n, g_guard, sizeof(g_guard) );
-
-        pnode->lptr = pnode->rptr = NULL;
-        pnode->len = n;
-        pnode->file = file;
-        pnode->line = line;
-        alloc_node** ppuplink = &g_vector_heap;
-        alloc_node* pcur = g_vector_heap;
-        while( pcur )
-        {
-            if( pnode == pcur )
-            {
-                dbgout( "*** FATAL: duplicate memory allocated ***" );
-                assert( false );
-                exit( -1 );
-            }
-            if( pnode < pcur )
-            {
-                ppuplink = &pcur->lptr;
-                pcur = pcur->lptr;
-            }
-            else
-            {
-                ppuplink = &pcur->rptr;
-                pcur = pcur->rptr;
-            }
-        }
-        *ppuplink = pnode;
-    }
-
-    return pmem;
-}
-
-void operator delete( void* p )
-{
-    if( !p ) return;
-    if( !g_heap )
-    {
-        dbgout( "*** FATAL: delete with empty heap ***" );
-        assert( false );
-        exit( -1 );
-    }
-
-    alloc_node* pcur = g_heap;
-    alloc_node** ppuplink = &g_heap;
-    while( pcur )
-    {
-        void* pcurblk = (char*)pcur + sizeof(alloc_node) + sizeof(g_guard);
-        if( p == pcurblk )
-        {
-            BYTE* pmem = (BYTE*)p;
-            if( memcmp( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) ) != 0 ||
-                memcmp( pmem + pcur->len, g_guard, sizeof(g_guard) ) != 0 )
-            {
-                dbgout( "*** FATAL: corrupted memory at %08X", p );
-                assert( false );
-                exit( -1 );
-            }
-            memset( pmem, time(NULL), pcur->len );
-            if( pcur->lptr && pcur->rptr )
-            {
-                // node has both ptrs so replace it with left child and move
-                // right child to bottom right of left child's tree
-                alloc_node* pend = pcur->lptr;
-                while( pend->rptr ) pend = pend->rptr;
-                *ppuplink = pcur->lptr;
-                pend->rptr = pcur->rptr;
-            }
-            else
-            {
-                // move child up
-                *ppuplink = (pcur->lptr) ? pcur->lptr : pcur->rptr;
-            }
-            free( pcur );
-            return;
-        }
-        if( p < pcurblk )
-        {
-            ppuplink = &pcur->lptr;
-            pcur = pcur->lptr;
-        }
-        else
-        {
-            ppuplink = &pcur->rptr;
-            pcur = pcur->rptr;
-        }
-    }
-
-    dbgout( "*** FATAL: delete on unalloced memory ***" );
-    assert( false );
-    exit( -1 );
-}
-
-void operator delete[]( void* p )
-{
-    if( !p ) return;
-    if( !g_vector_heap )
-    {
-        dbgout( "*** FATAL: delete with empty heap ***" );
-        assert( false );
-        exit( -1 );
-    }
-
-    alloc_node* pcur = g_vector_heap;
-    alloc_node** ppuplink = &g_vector_heap;
-    while( pcur )
-    {
-        void* pcurblk = (char*)pcur + sizeof(alloc_node) + sizeof(g_guard);
-        if( p == pcurblk )
-        {
-            BYTE* pmem = (BYTE*)p;
-            if( memcmp( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) ) != 0 ||
-                memcmp( pmem + pcur->len, g_guard, sizeof(g_guard) ) != 0 )
-            {
-                dbgout( "*** FATAL: corrupted memory at %08X", p );
-                assert( false );
-                exit( -1 );
-            }
-            memset( pmem, time(NULL), pcur->len );
-            if( pcur->lptr && pcur->rptr )
-            {
-                // node has both ptrs so replace it with left child and move
-                // right child to bottom right of left child's tree
-                alloc_node* pend = pcur->lptr;
-                while( pend->rptr ) pend = pend->rptr;
-                *ppuplink = pcur->lptr;
-                pend->rptr = pcur->rptr;
-            }
-            else
-            {
-                // move child up
-                *ppuplink = (pcur->lptr) ? pcur->lptr : pcur->rptr;
-            }
-            free( pcur );
-            return;
-        }
-        if( p < pcurblk )
-        {
-            ppuplink = &pcur->lptr;
-            pcur = pcur->lptr;
-        }
-        else
-        {
-            ppuplink = &pcur->rptr;
-            pcur = pcur->rptr;
-        }
-    }
-
-    dbgout( "*** FATAL: delete on unalloced memory ***" );
-    assert( false );
-    exit( -1 );
-}
-
-void* operator new( size_t n )
-{
-    return ::operator new( n, "(unknown)", 0 );
-}
-
-void* operator new[]( size_t n )
-{
-    return ::operator new[]( n, "(unknown)", 0 );
-}
-
-static void walk_alloc_tree( alloc_node* pcur, size_t* pttl )
-{
-    if( pcur )
-    {
-        walk_alloc_tree( pcur->lptr, pttl );
-        dbgout( "%s(%u): %u bytes at %08X", pcur->file, pcur->line,
-                pcur->len, (char*)pcur + sizeof(alloc_node) );
-        *pttl += pcur->len;
-        walk_alloc_tree( pcur->rptr, pttl );
-    }
-}
-
-void dump_alloc_heaps( void )
-{
-    if( g_heap || g_vector_heap )
-    {
-        size_t ttl = 0;
-        dbgout( "Memory leaks detected" );
-        dbgout( "=====================" );
-        dbgout( "" );
-
-        if( g_heap )
-        {
-            dbgout( "Scalar objects" );
-            dbgout( "--------------" );
-            walk_alloc_tree( g_heap, &ttl );
-            dbgout( "" );
-        }
-        if( g_vector_heap )
-        {
-            dbgout( "Vector objects" );
-            dbgout( "--------------" );
-            walk_alloc_tree( g_vector_heap, &ttl );
-            dbgout( "" );
-        }
-
-        dbgout( "=====================" );
-        dbgout( "Total bytes: %u", ttl );
-        dbgout( "=====================" );
-    }
 }
 
 #endif
